package com.dingding.special.order.confirm.biz.impl;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.model.push.PushModel;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.facade.queue.dto.push.PushRequestDTO;
import com.dingding.facade.queue.enums.ClientType;
import com.dingding.facade.queue.enums.PushType;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.order.common.dto.distance.ReqRealTimeCalculationDTO;
import com.dingding.order.common.dto.distance.ResRealTimeCalculationDTO;
import com.dingding.order.dto.publish.PushData;
import com.dingding.order.facade.common.distance.ICalculationFacade;
import com.dingding.special.order.aboard.code.ConfirmAboardCodeMsg;
import com.dingding.special.order.calculation.service.ICalculationAmountService;
import com.dingding.special.order.confirm.biz.IConfirmArriveService;
import com.dingding.special.order.confirm.dao.IConfirmArriveDao;
import com.dingding.special.order.confirm.dto.ConfirmArriveNoticeDTO;
import com.dingding.special.order.confirm.dto.ReqConfirmArriveDTO;
import com.dingding.special.order.confirm.dto.ResConfirmArriveDTO;

/**
 * 
 * @ClassName: IConfirmArriveService 
 * @Description: 确认到达 Service实现类
 * @author YHQ
 * @date 2016年8月21日 下午5:31:06
 * @since V2.4.0
 * 
 */
@Component("confirmArriveService")
public class ConfirmArriveServiceImpl implements IConfirmArriveService{

	private Logger log = Logger.getLogger(this.getClass());
	
	@Resource(name="confirmArriveDao")
	private IConfirmArriveDao confirmArriveDao;
	
	@Resource(name="queueService")
	private IQueueFacade queueFacade;
	
	@Resource(name = "calculationAmountService")
	private ICalculationAmountService calculationAmountService;
	
	@Resource(name = "calculationFacade")
	private ICalculationFacade calculationFacade;
	
	/**
	 * 
	 * @Title: confirmArrive 
	 * @Description: 确认到达
	 * @param reqConfirmArriveDTO 确认到达客户端请求Bean
	 * @author YHQ 
	 * @since V2.4.0
	 * @return ResponseEntity<ResConfirmArriveDTO>    返回类型
	 * 
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public ResponseEntity<ResConfirmArriveDTO> confirmArrive(ReqConfirmArriveDTO reqConfirmArriveDTO) {
		
		// 确认到达，客户端响应Bean
		ResponseEntity<ResConfirmArriveDTO> response = new ResponseEntity<ResConfirmArriveDTO>();
		
		// 判断是否符合确认到达条件
		boolean flag = this.validateParam(response, reqConfirmArriveDTO);
		
		if(!flag){
			return response;
		}
		
		ReqRealTimeCalculationDTO reqCalculationAmountDTO = new ReqRealTimeCalculationDTO();
		
		reqCalculationAmountDTO.setOid(reqConfirmArriveDTO.getOid());
		reqCalculationAmountDTO.setUserId(reqConfirmArriveDTO.getUserId());
		reqCalculationAmountDTO.setLatitude(reqConfirmArriveDTO.getDebusLatitude());
		reqCalculationAmountDTO.setLongitude(reqConfirmArriveDTO.getDebusLongitude());
		//计算类型  1:计算距离价格   2:实时计算距离价格 3：确认到达
		reqCalculationAmountDTO.setCalculationType(3);
		
		// 获取里程费用和订单里程
//		ResCalculationAmountDTO resCalculationAmount = calculationAmountService.calculationAmount(reqCalculationAmountDTO).getResponseBody();
		ResRealTimeCalculationDTO resCalculationAmount = calculationFacade.realTimeCalculation(reqCalculationAmountDTO);
		
		
		// 确认到达操作
		boolean operationResult = this.confirmArriveDao.confirmArriveOperation(response, reqConfirmArriveDTO,resCalculationAmount);
		
		// 通知
		if(operationResult){
			
			this.confirmArriveNotice(reqConfirmArriveDTO,resCalculationAmount);
		}
		
		return response;
	}

	
	/**
	 * 
	 * @Title: validateParam 
	 * @Description: 验证确认到达的条件  
	 * @param reqConfirmArriveDTO 确认到达客户端请求Bean
	 * @param response 确认到达，客户端响应Bean
	 * @author YHQ 
	 * @return boolean    返回类型
	 * 
	 */
	public boolean validateParam(ResponseEntity<ResConfirmArriveDTO> response,ReqConfirmArriveDTO reqConfirmArriveDTO){
		
		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqConfirmArriveDTO, ReqConfirmArriveDTO.class);

		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(ConfirmAboardCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(ConfirmAboardCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;
		}
		
		return true;
	}
	
	/**
	 * 
	 * @Title: confirmAboardNotice 
	 * @Description: 确认到达通知操作
	 * @param reqConfirmAboardDTO 确认到达客户端请求参数
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	public void confirmArriveNotice(ReqConfirmArriveDTO reqConfirmArriveDTO,ResRealTimeCalculationDTO resCalculationAmount){
		
		// 确认上车通知DTO
		ConfirmArriveNoticeDTO confirmArriveNoticeDTO = confirmArriveDao.getNoticeInfo(reqConfirmArriveDTO.getOid());
		
		if(confirmArriveNoticeDTO != null){
			
			// 金额
			confirmArriveNoticeDTO.setAmount(resCalculationAmount.getAmount());
			// 时长 
			confirmArriveNoticeDTO.setDuration(resCalculationAmount.getDuration());
			// 距离
			confirmArriveNoticeDTO.setDistance(resCalculationAmount.getDistance());
			
			// 推送消息
			this.confirmAboardPushMessage(confirmArriveNoticeDTO);
			// 司机确认上车-通知推送
			this.confirmAboardPushNotice(confirmArriveNoticeDTO);
		}
	}
	
	/**
	 * 
	 * @Title: confirmAboardPushMessage 
	 * @Description: 确认上车后推送消息
	 * @param confirmAboardNoticeDTO  确认上车，客户端请求参数
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	public void confirmAboardPushMessage(ConfirmArriveNoticeDTO confirmArriveNoticeDTO) {
		
		// 推送Bean
		PushData pushData = new PushData();

		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("specialConfirmArrivalPush");
		pushData.setResponseBody(confirmArriveNoticeDTO);

		PushRequestDTO pushRequestDTO = new PushRequestDTO();

		// 推送别名
		pushRequestDTO.setAliasId(confirmArriveNoticeDTO.getAliasId());
		pushRequestDTO.setAlert("确认到达");

		// 设备类型
		if (confirmArriveNoticeDTO.getClientType().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (confirmArriveNoticeDTO.getClientType().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}

		// 消息推送类型
		pushRequestDTO.setPushType(PushType.alert_msgcontent);

		// 推送类型
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));

		log.info("确认上车推送内容：" + JSONUtil.toJSONString(pushRequestDTO));
		
		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}

	/**
	 * 
	 * @Title: confirmAboardPushNotice 
	 * @Description: 确认上车后，通知推送消息
	 * @param confirmAboardNoticeDTO 确认上车，客户端请求参数
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	public void confirmAboardPushNotice(ConfirmArriveNoticeDTO confirmArriveNoticeDTO) {
		
		// 推送Bean
		PushData pushData = new PushData();
		
		String content = "司机已确认到达，请及时支付乘车费用，谢谢！";
		
		// 推送序号(时间戳)
		pushData.setRequestNumber(DateFormatUtil.getTimeInMillis().toString());
		// 推送时间
		pushData.setRequestTime(DateFormatUtil.yyyy_MM_dd_HHmmss());
		// 模块
		pushData.setModular("newsNoticePush");
		// 确认到达推送内容
		pushData.setResponseBody(PushModel.noticeModel(1, content, null));
		
		PushRequestDTO pushRequestDTO = new PushRequestDTO();
		
		// 推送别名
		pushRequestDTO.setAliasId(confirmArriveNoticeDTO.getAliasId());
		
		// 设备类型
		if (confirmArriveNoticeDTO.getClientType().equals("Android")) {
			pushRequestDTO.setClientType(ClientType.Android);
		} else if (confirmArriveNoticeDTO.getClientType().equals("iOS")) {
			pushRequestDTO.setClientType(ClientType.iOS);
		}
		
		// 消息推送类型
		pushRequestDTO.setPushType(PushType.msgcontent);
		
		// 推送类型
		pushRequestDTO.setPushContent(JSONUtil.toJSONString(pushData));
		
		log.info("确认上车通知内容：" + JSONUtil.toJSONString(pushRequestDTO));
		queueFacade.addPushToQueue(JSONUtil.toJSONString(pushRequestDTO));
	}

}
